#ifndef _CANARY2_UTIL_STR_H_
#define _CANARY2_UTIL_STR_H_

#include <compare>
#include <utility>
#include <cstring>
#include <algorithm>
#include <type_traits>
#include "concepts.h"
#include <string>
#include <string_view>

namespace wilson::util
{
    template<typename StringLike>
    StringLike trim(const StringLike& str, typename StringLike::value_type delim = {' '})
    {
        using size_type   = typename StringLike::size_type;
        using traits_type = typename StringLike::traits_type;

        auto space_char = delim;
        size_type i;
        for (i = 0; i < str.size(); ++i)
        {
            if (str[i] != space_char) break;
        }
        size_type newstr_beg = i;
        for (i = str.size() - 1; i > newstr_beg - 1; --i)
        {
            if (str[i] != space_char) break;
        }
        size_type newstr_end = i + 1;
        
        return str.substr(newstr_beg, newstr_end - 1);
    }

    template<typename StringLike>
    StringLike remove_quotation_mark(const StringLike& str)
    {
        return trim(str, '"');
    }

    template<typename StringViewLike1, typename StringViewLike2>
    ::std::strong_ordering strv_case_cmp(StringViewLike1&& s1, StringViewLike2&& s2) noexcept
    {
        using size_type = typename ::std::remove_reference_t<StringViewLike1>::size_type;
        size_type len1 = s1.size(), len2 = s2.size();
        auto result = ::strncasecmp(s1.data(), s2.data(), ::std::min(len1, len2));
        if (result == 0)
        {
            if (len1 == len2) return ::std::strong_ordering::equal;
            else if (len1 < len2) return ::std::strong_ordering::less;
            else return ::std::strong_ordering::greater;
        }
        else if (result < 0) return ::std::strong_ordering::less;
        return ::std::strong_ordering::greater;
    }

    template<typename StringViewLike1, typename StringViewLike2>
    bool strv_case_equal(StringViewLike1&& s1, StringViewLike2&& s2) noexcept
    {
        return strv_case_cmp(
            ::std::string_view{::std::forward<StringViewLike1>(s1)}, 
            ::std::string_view{::std::forward<StringViewLike2>(s2)}
        ) == ::std::strong_ordering::equal;
    }

    
}

#endif
